package com.huihuiyun.huihuiyun.server.controller.member.client;

import com.huihuiyun.huihuiyun.server.ApplicationConst;
import com.huihuiyun.huihuiyun.server.controller.member.client.viewobjects.HhyOrderItemVO;
import com.huihuiyun.huihuiyun.server.controller.member.client.viewobjects.HhyOrderVO;
import com.huihuiyun.huihuiyun.server.domain.*;
import com.huihuiyun.huihuiyun.server.service.*;
import com.huihuiyun.huihuiyun.server.viewobject.ResultVO;
import com.huihuiyun.huihuiyun.server.viewobject.ResultVOUtil;
import com.mark.util.JaxrsUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

@Component
@Path(Const.context)
@Slf4j
public class MemberClientOrderController {
    @Context
    private HttpServletResponse httpServletResponse;

    @Autowired
    private HhyMemberService memberService;

    @Autowired
    private HhyAreaService areaService;

    @Autowired
    private HhyProductCategoryService hhyProductCategoryService;

    @Autowired
    private HhyProductService hhyProductService;

    @Autowired
    private HhyOrderService hhyOrderService;

    @Autowired
    private HhyOrderItemService hhyOrderItemService;

    @Autowired
    private HhySellerService hhySellerService;

    @Autowired
    private HhyWalletService hhyWalletService;

    @Autowired
    private HhyMemberShoppingCartService hhyShoppingCartService;

    /*******************
     * order
     ******************/
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/productBuyNow")
    public HhyOrder productBuyNow(@QueryParam("memberId") String memberId, @QueryParam("productId") String productId, @QueryParam("quantity") int quantity) {
        try {
            HhyProduct hhyProduct = hhyProductService.findOne(productId);

            HhyOrder hhyOrder = new HhyOrder();
            hhyOrder.sellerId = hhyProduct.sellerId;
            hhyOrder.status = HhyOrder.status0WaitingMemberPay;
            hhyOrder.memberId = memberId;
            hhyOrder = hhyOrderService.post(hhyOrder);

            HhyOrderItem hhyOrderItem = new HhyOrderItem();
            hhyOrderItem.orderId = hhyOrder.id;
            hhyOrderItem.originalPrice = hhyProduct.originalPrice;
            hhyOrderItem.memberPrice = hhyProduct.memberPrice;
            hhyOrderItem.extraPoints = hhyProduct.extraPoints;
            hhyOrderItem.quantity = quantity;
            hhyOrderItemService.post(hhyOrderItem);

            return hhyOrder;
        } catch (Exception e) {
            log.error("", e);
            JaxrsUtil.setHttpServletResponseInternalServerError(httpServletResponse);
            return null;
        }
    }

    /**
     * 可能下发多个商家的货品
     *
     * @param hhyOrderVO
     * @return
     */
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @Path("/order/buyNow")
    public ResultVO<List<HhyOrderVO>> buyNow(HhyOrderVO hhyOrderVO) {
        try {
            Map<String, HhyOrder> sellerOrderMap = new HashMap<>();
            Map<String, List<HhyOrderItem>> sellerOrderItemMap = new HashMap<>();
            for (HhyOrderItemVO hhyOrderItemVO : hhyOrderVO.hhyOrderItemVOList) {

                String productId = hhyOrderItemVO.productId;
                HhyProduct hhyProduct = hhyProductService.findOne(productId);

                HhyOrderItem hhyOrderItem = new HhyOrderItem();
                hhyOrderItem.quantity = hhyOrderItemVO.quantity;
                hhyOrderItem.originalPrice = hhyProduct.originalPrice;
                hhyOrderItem.memberPrice = hhyProduct.memberPrice;
                hhyOrderItem.extraPoints = hhyProduct.extraPoints;
                String sellerId = hhyProduct.sellerId;

                if (!sellerOrderMap.containsKey(sellerId)) {
                    HhyOrder hhyOrder = new HhyOrder();
                    hhyOrder.memberId = hhyOrderVO.memberId;
                    hhyOrder.sellerId = sellerId;
                    HhySeller hhySeller = hhySellerService.findOne(sellerId);
                    hhyOrder.sellerName = hhySeller.name;
                    hhyOrder.addressName = hhyOrderVO.addressName;
                    hhyOrder.addressPhone = hhyOrderVO.addressPhone;
                    hhyOrder.addressAreaCode = hhyOrderVO.addressAreaCode;//fixme 这里要看看
                    hhyOrder.addressDetail = hhyOrderVO.addressDetail;
                    sellerOrderMap.put(sellerId, hhyOrder);
                }
                HhyOrder hhyOrder = sellerOrderMap.get(sellerId);
                hhyOrderItem.totalMoney = hhyOrderItem.memberPrice * hhyOrderItem.quantity;
                //额外赠送积分 = 额外赠送积分*数量
                hhyOrderItem.totalExtraPoints = +hhyOrderItem.extraPoints * hhyOrderItem.quantity;
                hhyOrder.totalMoney = hhyOrder.totalMoney + hhyOrderItem.totalMoney;
                //不能由子订单算积分累加，
                //累加  1(1.99) + 0(0.01) = 1,
                //汇总  2(1.99 + 0.01) = 2,
                //商品积分(总) = 总价(元) * 1积分/元 = (总价(分)/100) * 1积分/元
                hhyOrder.memberProductPoints = hhyOrder.totalMoney / 100 * 1;
                hhyOrder.memberExtraPoints = hhyOrder.memberExtraPoints + hhyOrderItem.extraPoints;
                hhyOrder.memberPoints = hhyOrder.memberProductPoints + hhyOrder.memberExtraPoints;

                if (!sellerOrderItemMap.containsKey(sellerId)) {
                    sellerOrderItemMap.put(sellerId, new Vector<>());
                }
                List<HhyOrderItem> hhyOrderItemList = sellerOrderItemMap.get(sellerId);
                hhyOrderItemList.add(hhyOrderItem);
            }

            List<HhyOrderVO> hhyOrderVOList = new Vector<>();
            for (String sellerId : sellerOrderMap.keySet()) {
                HhyOrder hhyOrder = sellerOrderMap.get(sellerId);
                hhyOrder = hhyOrderService.post(hhyOrder);

                HhyOrderVO hhyOrderVONew = ResultVOUtil.copyProperties(hhyOrder, HhyOrderVO.class);

                String orderId = hhyOrder.id;
                List<HhyOrderItemVO> hhyOrderItemVOList = new Vector<>();
                List<HhyOrderItem> hhyOrderItemList = sellerOrderItemMap.get(sellerId);
                //后续改为批量操作
                for (HhyOrderItem hhyOrderItem : hhyOrderItemList) {
                    hhyOrderItem.orderId = orderId;
                    hhyOrderItem = hhyOrderItemService.post(hhyOrderItem);
                    HhyOrderItemVO hhyOrderItemVO = ResultVOUtil.copyProperties(hhyOrderItem, HhyOrderItemVO.class);
                    hhyOrderItemVOList.add(hhyOrderItemVO);
                }
                hhyOrderVONew.hhyOrderItemVOList = hhyOrderItemVOList;
                hhyOrderVOList.add(hhyOrderVONew);
            }
            return ResultVOUtil.success(hhyOrderVOList);
        } catch (Exception e) {
            log.error("", e);
            return ResultVOUtil.error("操作失败，请稍后重试。");
        }
    }

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @Path("/order/pay")
    public ResultVO<HhyOrderVO> pay(HhyOrderVO hhyOrderVO) {
        try {
            String hhyOrderId = hhyOrderVO.id;
            //订单更新状态
            HhyOrder hhyOrder = hhyOrderService.findOne(hhyOrderId);
            if (hhyOrder.status != HhyOrder.status0WaitingMemberPay) {
                return ResultVOUtil.error("订单状态不是【待支付】");
            }

            String walletIdHuihuiyun = ApplicationConst.WalletIdHuihuiyun;

            long totalMoney = hhyOrder.totalMoney;
            //更新平台现金账户
            hhyWalletService.addMoney(walletIdHuihuiyun, totalMoney);

            //更新平台积分 = 总金额(分)
            long points = hhyOrder.totalMoney;
            hhyWalletService.addPoints(walletIdHuihuiyun, points);

            hhyOrder = sharePoints(hhyOrder);

            hhyOrder.status = HhyOrder.status10WaitingSellerSendProduct;
            hhyOrder = hhyOrderService.put(hhyOrder);

            hhyOrderVO = ResultVOUtil.copyProperties(hhyOrder, HhyOrderVO.class);
            return ResultVOUtil.success(hhyOrderVO);
        } catch (Exception e) {
            log.error("", e);
            return ResultVOUtil.error("操作失败，请稍后重试。");
        }
    }

    private HhyOrder sharePoints(HhyOrder hhyOrder) {
        HhyMember member = memberService.findOne(hhyOrder.memberId);
        HhySeller seller = hhySellerService.findOne(hhyOrder.sellerId);

        String memberAreaCode = member.areaCode;
        String sellerAreaCode = seller.areaCode;

        String memberDistrictAreaCode = memberAreaCode;
        String memberCityAreaCode = getCityAreaIdByDistrictAreaId(memberAreaCode);
        String memberProvinceAreaCode = getProvinceAreaIdByDistrictAreaId(memberAreaCode);

        String sellerDistrictAreaCode = sellerAreaCode;
        String sellerCityAreaCode = getCityAreaIdByDistrictAreaId(sellerAreaCode);
        String sellerProvinceAreaCode = getProvinceAreaIdByDistrictAreaId(sellerAreaCode);

        String huihuiyunWalletId = ApplicationConst.WalletIdHuihuiyun;
        String memberWalletId = member.walletId;
        String sellerWalletId = seller.walletId;
        String memberRecommenderWalletId = member.partnerWalletId != null ? member.partnerWalletId : ApplicationConst.WalletIdHuihuiyun;//如果推荐人为空，用平台账号
        String memberDistrictAgentSellerWalletId = getIfWalletByAreaId(memberDistrictAreaCode);
        String memberCityAgentSellerWalletId = getIfWalletByAreaId(memberCityAreaCode);
        String memberProvinceAgentSellerWalletId = getIfWalletByAreaId(memberProvinceAreaCode);
        String sellerDistrictAgentSellerWalletId = getIfWalletByAreaId(sellerDistrictAreaCode);
        String sellerCityAgentSellerWalletId = getIfWalletByAreaId(sellerCityAreaCode);
        String sellerProvinceAgentSellerWalletId = getIfWalletByAreaId(sellerProvinceAreaCode);

        //汇惠云分配比例， 默认5 (%)
        int huihuiyunShareRate = seller.rate;

        //订单总积分 = 总金额(分)
        long totalPoints = hhyOrder.totalMoney;

        //平台抽取积分 = 订单总积分 * 分成比例%
        long huihuiyunSharePoints = totalPoints * huihuiyunShareRate / 100;

        long memberPoints = hhyOrder.memberPoints;

        long totalExtraPoints = hhyOrder.memberExtraPoints;

        //商家积分 = 订单总积分 - 平台抽取积分 - 赠送积分
        long sellerPoints = totalPoints - huihuiyunSharePoints - totalExtraPoints;

        //用户推荐人积分 = 订单总积分 * 1%
        long memberRecommenderPoints = totalPoints * 1 / 100;

        //用户所在区代理商积分 = 订单总积分 * (平台分配比例-2)% * 5%
        long memberDistrictAgentSellerPoints = totalPoints * ((huihuiyunShareRate - 2)) / 100 * (5 / 100);

        //用户所在市代理商积分 = 订单总积分 * (平台分配比例-2)% * 10%
        long memberCityAgentSellerPoints = totalPoints * ((huihuiyunShareRate - 2)) / 100 * (10 / 100);

        //用户所在省代理商积分 = 订单总积分 * (平台分配比例-2)% * 10%
        long memberProvinceAgentSellerPoints = totalPoints * ((huihuiyunShareRate - 2)) / 100 * (10 / 100);

        //商家所在区代理商积分 = 订单总积分 * (平台分配比例-2)% * 15%
        long sellerDistrictAgentSellerPoints = totalPoints * ((huihuiyunShareRate - 2)) / 100 * (15 / 100);

        //商家所在市代理商积分 = 订单总积分 * (平台分配比例-2)% * 2%
        long sellerCityAgentSellerPoints = totalPoints * ((huihuiyunShareRate - 2)) / 100 * (2 / 100);

        //商家所在省代理商积分 = 订单总积分 * (平台分配比例-2)% * (100-5-10-10-15-2)% * 49%
        long sellerProvinceAgentSellerPoints = totalPoints * ((huihuiyunShareRate - 2)) / 100 * (100 - 5 - 10 - 10 - 15 - 2) * (49 / 100);

        long huihuiyunPoints = totalPoints - memberPoints - sellerPoints - memberRecommenderPoints
                - memberDistrictAgentSellerPoints - memberCityAgentSellerPoints - memberProvinceAgentSellerPoints
                - sellerDistrictAgentSellerPoints - sellerCityAgentSellerPoints - sellerProvinceAgentSellerPoints;

        //积分转账
        hhyWalletService.transferPoints(huihuiyunWalletId, memberWalletId, memberPoints);
        hhyWalletService.transferPoints(huihuiyunWalletId, sellerWalletId, sellerPoints);
        hhyWalletService.transferPoints(huihuiyunWalletId, memberRecommenderWalletId, memberRecommenderPoints);
        hhyWalletService.transferPoints(huihuiyunWalletId, memberDistrictAgentSellerWalletId, memberDistrictAgentSellerPoints);
        hhyWalletService.transferPoints(huihuiyunWalletId, memberCityAgentSellerWalletId, memberCityAgentSellerPoints);
        hhyWalletService.transferPoints(huihuiyunWalletId, memberProvinceAgentSellerWalletId, memberProvinceAgentSellerPoints);
        hhyWalletService.transferPoints(huihuiyunWalletId, sellerDistrictAgentSellerWalletId, sellerDistrictAgentSellerPoints);
        hhyWalletService.transferPoints(huihuiyunWalletId, sellerCityAgentSellerWalletId, sellerCityAgentSellerPoints);
        hhyWalletService.transferPoints(huihuiyunWalletId, sellerProvinceAgentSellerWalletId, sellerProvinceAgentSellerPoints);

        hhyOrder.sellerPoints = sellerPoints;
        hhyOrder.memberRecommenderPoints = memberRecommenderPoints;
        hhyOrder.memberDistrictAgentSellerPoints = memberDistrictAgentSellerPoints;
        hhyOrder.memberCityAgentSellerPoints = memberCityAgentSellerPoints;
        hhyOrder.memberProvinceAgentSellerPoints = memberProvinceAgentSellerPoints;
        hhyOrder.sellerDistrictAgentSellerPoints = sellerDistrictAgentSellerPoints;
        hhyOrder.sellerCityAgentSellerPoints = sellerCityAgentSellerPoints;
        hhyOrder.sellerProvinceAgentSellerPoints = sellerProvinceAgentSellerPoints;
        hhyOrder.huihuiyunPoints = huihuiyunPoints;
        return hhyOrder;
    }

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @Path("/order/receiveProduct")
    public ResultVO receiveProduct(HhyOrderVO hhyOrderVO) {
        try {
            String hhyOrderId = hhyOrderVO.id;
            //订单更新状态
            HhyOrder hhyOrder = hhyOrderService.findOne(hhyOrderId);
            if (hhyOrder.status != HhyOrder.status20WaitingMemberReceiveProduct) {
                return ResultVOUtil.error("订单状态不是【待收货】");
            }

            hhyOrder.status = HhyOrder.status30FinishAndWaitingMemberComment;
            hhyOrder = hhyOrderService.put(hhyOrder);

            hhyOrderVO = ResultVOUtil.copyProperties(hhyOrder, HhyOrderVO.class);
            return ResultVOUtil.success(hhyOrderVO);
        } catch (Exception e) {
            log.error("", e);
            return ResultVOUtil.error("操作失败，请稍后重试。");
        }
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/addToShoppingCart")
    public HhyMemberShoppingCart addToShoppingCart(@QueryParam("memberId") String memberId, @QueryParam("productId") String productId, @QueryParam("quantity") int quantity) {
        try {
            HhyProduct hhyProduct = hhyProductService.findOne(productId);

            HhyMemberShoppingCart hhyShoppingCart = new HhyMemberShoppingCart();

            hhyShoppingCart.sellerId = hhyProduct.sellerId;
            hhyShoppingCart.productId = hhyProduct.id;
            hhyShoppingCart.productIcon = hhyProduct.icon;
            hhyShoppingCart.memberId = memberId;
            hhyShoppingCart.productOriginalPrice = hhyProduct.originalPrice;
            hhyShoppingCart.productMemberPrice = hhyProduct.memberPrice;
            hhyShoppingCart.productQuantity = quantity;
            hhyShoppingCart.productExtraPoints = hhyProduct.extraPoints;

            hhyShoppingCart = hhyShoppingCartService.post(hhyShoppingCart);
            return hhyShoppingCart;
        } catch (Exception e) {
            log.error("", e);
            JaxrsUtil.setHttpServletResponseInternalServerError(httpServletResponse);
            return null;
        }
    }

//    @GET
//    @Produces(MediaType.APPLICATION_JSON)
//    @Path("/findOrderById")
//    public HhyOrder findOrderById(@QueryParam("id") String id) {
//        try {
//            HhyOrder hhyOrder = hhyOrderService.findOne(id);
//            return hhyOrder;
//        } catch (Exception e) {
//            log.error("", e);
//            JaxrsUtil.setHttpServletResponseInternalServerError(httpServletResponse);
//            return null;
//        }
//    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/findOrderListByMemberIdAndStatus")
    public List<HhyOrder> findOrderListByMemberIdAndStatus(@QueryParam("memberId") String memberId, @QueryParam("status") int status) {
        try {
            List<HhyOrder> hhyOrderList = hhyOrderService.findOrderListByMemberIdAndStatus(memberId, status);
            return hhyOrderList;
        } catch (Exception e) {
            log.error("", e);
            JaxrsUtil.setHttpServletResponseInternalServerError(httpServletResponse);
            return null;
        }
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/order/listByMemberId")
    public ResultVO<List<HhyOrderVO>> listByMemberId(@QueryParam("memberId") String memberId) {
        try {
            List<HhyOrder> hhyOrderList = hhyOrderService.findOrderListByMemberId(memberId);
            List<HhyOrderVO> hhyOrderVOList = ResultVOUtil.copyProperties(hhyOrderList, HhyOrderVO.class);
            return ResultVOUtil.success(hhyOrderVOList);
        } catch (Exception e) {
            log.error("", e);
            return ResultVOUtil.error();
        }
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/order/listByMemberIdAndStatus")
    public ResultVO<List<HhyOrderVO>> listByMemberIdAndStatus(@QueryParam("memberId") String memberId, @QueryParam("status") int status) {
        try {
            List<HhyOrder> hhyOrderList = hhyOrderService.findOrderListByMemberIdAndStatus(memberId, (int) status);
            List<HhyOrderVO> hhyOrderVOList = ResultVOUtil.copyProperties(hhyOrderList, HhyOrderVO.class);
            return ResultVOUtil.success(hhyOrderVOList);
        } catch (Exception e) {
            log.error("", e);
            return ResultVOUtil.error();
        }
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/order/findOrderById")
    public ResultVO<HhyOrderVO> findOrderById(@QueryParam("id") String id) {
        try {
            HhyOrder hhyOrder = hhyOrderService.findOne(id);
            HhyOrderVO hhyOrderVO = ResultVOUtil.convert(hhyOrder, HhyOrderVO.class);
            return ResultVOUtil.success(hhyOrderVO);
        } catch (Exception e) {
            log.error("", e);
            return ResultVOUtil.error();
        }
    }

    @POST
    @Path("/order/updateOrderMemberAddress")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public ResultVO<HhyOrderVO> updateOrderMemberAddress(HhyOrderVO hhyOrderVO) {
        try {
            String id = hhyOrderVO.id;
            HhyOrder hhyOrder = hhyOrderService.findOne(id);
            hhyOrder.addressName = hhyOrderVO.addressName;
            hhyOrder.addressPhone = hhyOrderVO.addressPhone;
            hhyOrder.addressAreaCode = hhyOrderVO.addressAreaCode;
            hhyOrder.addressDetail = hhyOrderVO.addressDetail;
            hhyOrder = hhyOrderService.put(hhyOrder);
            hhyOrderVO = ResultVOUtil.convert(hhyOrder, HhyOrderVO.class);
            return ResultVOUtil.success(hhyOrderVO);
        } catch (Exception e) {
            log.error("", e);
            return ResultVOUtil.error();
        }
    }

    private String getProvinceAreaIdByDistrictAreaId(String areaCode) {
        HhyArea area = areaService.findAreaByCode(areaCode);
        String province = area.province;
        String city = HhyArea.NONE;
        String district = HhyArea.NONE;
        HhyArea areaProvince = areaService.findAreaByProvinceAndCityAndDistrict(province, city, district);
        return areaProvince.id;
    }

    private String getCityAreaIdByDistrictAreaId(String areaId) {
        HhyArea area = areaService.findAreaByCode(areaId);
        String province = area.province;
        String city = area.city;
        String district = HhyArea.NONE;
        HhyArea areaProvince = areaService.findAreaByProvinceAndCityAndDistrict(province, city, district);
        return areaProvince.id;
    }

    private String getIfWalletByAreaId(String areaId) {
        String hhyWalletId = "AreaId" + areaId;
        HhyWallet hhyWallet = hhyWalletService.findIf(hhyWalletId);
        return hhyWallet.id;
    }
}